package com.streetsmart.main;

/**
 * Contains the main activity where the user can input time available and return location. 
 * On hitting plan the user is given a schedule. The user can also uses the menus in the 
 * bottom to either report or manage tasks
 */
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Calendar;

import org.json.JSONException;

import com.streetsmart.AlarmReceiver;
import com.streetsmart.DBManager;
import com.streetsmart.LocationService;
import com.streetsmart.R;
import com.streetsmart.Utilities;
import com.streetsmart.MySuggestionsAdapter;
import com.streetsmart.test.TestActivity;

import android.app.Activity;
import android.app.AlarmManager;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.provider.Settings;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.EditText;
import android.widget.SeekBar;
import android.widget.SimpleCursorAdapter;
import android.widget.Spinner;
import android.widget.TextView;
//TODO add menu to set HOME and Work locations.
// TODO add menu to remove completed events
import android.widget.Toast;

public class SSMainActivity extends Activity implements
		SeekBar.OnSeekBarChangeListener, OnItemSelectedListener {

	SeekBar seekBar;
	TextView textView;
	TextView textViewAddress;
	Spinner spinner;
	Context context = this;
	String address;
	private String temp = "";
	float time = 1;
	Intent intent;
	DBManager dbManager;
	String place = "HOME";
	double lat;
	double lng;
	boolean isCurrent;
	Utilities uti;

	// Also starts the alarm manager to periodically send notifications to the
	// user.
	@Override
	public void onCreate(Bundle savedInstanceState) {

		// TODO Add a database table and get the cursor from a query.

		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
		setContentView(R.layout.ssmain);
		getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,
				R.layout.sswindow_title);
		dbManager = new DBManager(context);

		// ****
		// mdbmanager.setFirstRecentLocation();
		// mdbmanager.setLastRecentLocation();
		uti = new Utilities(context);
		Context context = getApplicationContext();
		Calendar time = Calendar.getInstance();
		time.set(Calendar.HOUR_OF_DAY, 14);
		time.set(Calendar.MINUTE, 9);
		time.set(Calendar.SECOND, 0);
		AlarmManager alarmMgr = (AlarmManager) context
				.getSystemService(Context.ALARM_SERVICE);
		Intent intent = new Intent(context, AlarmReceiver.class);
		intent.putExtra("PERIODIC", "true");
		PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
				intent, 0);
		Log.i("StreetSmart-Log", "AlarmManager invoked");
		alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(),
				3 * 60 * 60 * 1000, pendingIntent);

		seekBar = (SeekBar) findViewById(R.id.seekTimeInHand);
		seekBar.incrementProgressBy(30);
		seekBar.setProgress(90);
		seekBar.setOnSeekBarChangeListener(this);
		textView = (TextView) findViewById(R.id.textTimeInHand);
		textViewAddress = (TextView) findViewById(R.id.textViewAddress);
		spinner = (Spinner) findViewById(R.id.spinnerReturnLocation);
	}

	@Override
	public void onResume() {
		super.onResume();
		checkLocationService();
		boolean isInternetConnected = hasActiveInternetConnection(context);
		if (!isInternetConnected) {/*
									 * Toast m = Toast.makeText(mcontext,
									 * "This application requires Internet. Please change your settings"
									 * , Toast.LENGTH_LONG); m.show();
									 */
			showNoConnectionDialog(context);
		}
		initActivity();
	}

	public void initActivity() {
		textView.setText("" + time + "hour");
		ArrayAdapter<CharSequence> marrayAdapter = ArrayAdapter
				.createFromResource(context, R.array.returnLocations,
						android.R.layout.simple_spinner_item);
		marrayAdapter
				.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

		spinner.setAdapter(marrayAdapter);
		spinner.setOnItemSelectedListener(this);
		spinner.setSelected(true);
		spinner.setSelection(2);
	}

	public void onProgressChanged(SeekBar seekBar, int progress,
			boolean fromUser) {

		// TODO Pass this value to the system to store.

		time = (progress / 30) / 2.0f;

		textView.setText("" + time + "hours");
	}

	public void onStartTrackingTouch(SeekBar seekBar) {
	}

	public void onStopTrackingTouch(SeekBar seekBar) {
	}

	public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,
			long arg3) {
		/*
		 * // TODO Pass this value to the next activity // TODO check if the
		 * item is present in the database. check either by // name or the
		 * actual address. The table should contain all strings id, // name,
		 * lat, lng, address
		 */
		Cursor cur;
		place = arg0.getItemAtPosition(arg2).toString();
		dbManager.close();
		if (place.equals("CURRENT")) { // -----> if the user chooses to return
										// to the current location
			cur = dbManager.getMostRecentLocation();

			if (cur.getCount() > 0) {
				cur.moveToFirst();
				double lat = cur.getDouble(1);
				double lng = cur.getDouble(2);
				// cur.close();
				double[] geocode = { lat, lng };
				try {
					address = Utilities.getAddress(geocode);
				} catch (JSONException e) {
					// TODO Auto-generated catch block e.printStackTrace();
				}
				this.lat = lat;
				this.lng = lng;
				isCurrent = true;
				textViewAddress.setText("");
				if (address.length() > 25) {
					textViewAddress.setText(address.substring(0, 24) + "...");
				} else
					textViewAddress.setText(address);
			}
			// cur.close();

			/*
			 * maddress = "3577-3699 19th Ave, San Francisco, CA 94132, USA";
			 * lat = 37.72126410; lng = -122.47534920; isCurrent = true; if
			 * (maddress.length() > 25) {
			 * mTextViewAddress.setText(maddress.substring(0, 24) + "..."); }
			 * else mTextViewAddress.setText(maddress); cur.close();
			 */
		} else { // -----> If the user chooses to return to either home or work
					// place
			cur = dbManager.getReturnLocation(place);
			MySuggestionsAdapter suggestionsList = null;
			if (cur.getCount() == 0) {
				// if the home or work location is not yet known get it
				// from the user as a one time process
				// cur.close();
				// mdbmanager.close();
				LayoutInflater mlayoutInteface = LayoutInflater.from(context);
				View mprompts = mlayoutInteface.inflate(
						R.layout.ssget_address_dialog, null);

				AlertDialog.Builder malertDialogBuilder = new AlertDialog.Builder(
						context);

				malertDialogBuilder.setView(mprompts);
				final AutoCompleteTextView muserInput = (AutoCompleteTextView) mprompts
						.findViewById(R.id.editTextgetAddress);
				cur.close();
				dbManager.close();

				Cursor mcur = dbManager.getAllUserAddresses("");
				suggestionsList = new MySuggestionsAdapter(context, mcur);
				muserInput.setAdapter(suggestionsList);
				mcur.close();
				dbManager.close();

				malertDialogBuilder.setCancelable(false).setPositiveButton(
						"OK", new DialogInterface.OnClickListener() {

							boolean result = false;

							public void onClick(DialogInterface dialog,
									int which) {
								result = true;
								textView.setTextColor(android.R.color.white);
								address = muserInput.getText().toString();
								try {
									if (!dbManager.checkIfPresent(address)) {
										result = dbManager
												.saveRecentUserAddress(address);
									}
									if (result) {
										dbManager.saveReturnLocation(place,
												address);
										ContentValues cv = dbManager
												.getUserAddressDetails(address);
										lat = cv.getAsDouble("latitude");
										lng = cv.getAsDouble("longitude");
										isCurrent = false;
									} else {
										address = "Invalid address. Try again!";
									}
								} catch (JSONException e) { // TODO
															// Auto-generated
															// catch block
									e.printStackTrace();
								} // hack to get the UI pretty
								if (result) {
									if (address.length() > 25) {
										textViewAddress.setText(address
												.substring(0, 24) + "...");
									} else {
										textViewAddress.setText(address);
									}
								} else {
									//textViewAddress.setTextColor(R.color.red);
									textViewAddress.setText(address);
								}
							}

						});
				AlertDialog malertDialog = malertDialogBuilder.create();
				malertDialog.show();

			} else {
				// -> if the user has not already mentioned
				// the address of home or work
				cur.moveToFirst();
				address = cur.getString(cur.getColumnIndex("address"));
				lat = cur.getDouble(cur.getColumnIndex("latitude"));
				lng = cur.getDouble(cur.getColumnIndex("longitude"));
				isCurrent = false;
				// cur.close();
				// mdbmanager.close();
				// hack to get the UI pretty
				if (address.length() > 25) {
					textViewAddress.setText(address.substring(0, 24) + "...");
				} else
					textViewAddress.setText(address);
			}
			if (suggestionsList != null) {
				suggestionsList.close();
			}
		}
		cur.close();
		dbManager.close();
	}

	public void onNothingSelected(AdapterView<?> arg0) {
		address = "";
		// get current location and add it to the database if not already
		// present
		// address = getCurrentLocation();
		// storeAddressInToReturnLocations(address);
	}

	public void onClickGo(View v) {
		// add activity for schedule display here and pass on time and address.
		intent = new Intent(this, SSScheduleDisplayActivity.class);
		intent.putExtra("latitude", this.lat);
		intent.putExtra("longitude", this.lng);
		intent.putExtra("address", address);
		intent.putExtra("time", time);
		intent.putExtra("isCurrent", isCurrent);
		startActivity(intent);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.ssoptions, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.mnuReport:
			intent = new Intent(this, SSReportTaskActivity.class);
			startActivity(intent);
			return true;
		case R.id.mnuOverView:
			intent = new Intent(this, SSTaskOverviewActivity.class);
			startActivity(intent);
			return true;
		default:
			return super.onOptionsItemSelected(item);
		}
	}

	public void onBackPressed() {
		dbManager.close();
		finish();
	}

	@Override
	public void onDestroy() {
		dbManager.close();
		super.onDestroy();
	}

	/**
	 * Display a dialog suggestin there is no active internet connection and
	 * take the user to network settings
	 * 
	 * @param ctx1
	 */
	public static void showNoConnectionDialog(Context ctx1) {
		final Context context = ctx1;
		AlertDialog.Builder builder = new AlertDialog.Builder(context);
		builder.setCancelable(true);
		builder.setMessage("Please login to your wifi or change your settings");
		builder.setTitle("Application requires active internet");
		builder.setPositiveButton("settings",
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						context.startActivity(new Intent(
								Settings.ACTION_WIRELESS_SETTINGS));
					}
				});
		builder.setNegativeButton("cancel",
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						return;
					}
				});
		builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
			public void onCancel(DialogInterface dialog) {
				return;
			}
		});

		builder.show();
	}

	/**
	 * if the gps provider is turned off pop a dialog showing there is no
	 * location data. and take the user to location settings
	 * 
	 * @param ctx1
	 */
	public static void showNoLocationProvider(Context ctx1) {
		final Context ctx = ctx1;
		AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
		builder.setCancelable(true);
		builder.setMessage("Please change your location settings");
		builder.setTitle("Application requires a location provider");
		builder.setPositiveButton("settings",
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						ctx.startActivity(new Intent(
								Settings.ACTION_SECURITY_SETTINGS));
					}
				});
		builder.setNegativeButton("cancel",
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						return;
					}
				});
		builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
			public void onCancel(DialogInterface dialog) {
				return;
			}
		});

		builder.show();
	}

	/**
	 * enable the location service. this starts to collect the user location
	 * periodically
	 */
	private void checkLocationService() {
		/*
		 * Log.d("CHECK_SERVICE", "Service running: " +
		 * (settings.getBoolean("locationService", false)?"YES":"NO"));
		 * 
		 * if(settings.getBoolean("locationService", false)) return;
		 */
		LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		if (!lm.isProviderEnabled(LocationManager.GPS_PROVIDER)
				&& !lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
			showNoLocationProvider(context);
		} else {
			Intent mServiceIntent = new Intent(this, LocationService.class);
			startService(mServiceIntent);
		}
	}

	/**
	 * checks whether there is active network connection. Sometime you need to
	 * login to the wifi to use it. So only after login in it becomes active
	 * checks if you can open a page like for ex. google.om
	 * 
	 * @param context
	 * @return
	 */
	public boolean hasActiveInternetConnection(Context context) {
		if (isNetworkAvailable()) {
			try {
				HttpURLConnection urlc = (HttpURLConnection) (new URL(
						"http://www.google.com").openConnection());
				urlc.setRequestProperty("User-Agent", "Test");
				urlc.setRequestProperty("Connection", "close");
				urlc.setConnectTimeout(0);
				urlc.connect();
				int responseCode = urlc.getResponseCode();
				urlc.disconnect();
				if (responseCode == 200) {
					return true;
				}
				return false;
			} catch (IOException e) {
				Log.e("com.streetsmart", "Error checking internet connection",
						e);
				return false;
			}
		} else {
			Log.d("com.streetsmart", "No network available!");
			return false;
		}

	}

	/**
	 * checks whether a network is available
	 * 
	 * @return
	 */
	private boolean isNetworkAvailable() {
		ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo activeNetworkInfo = connectivityManager
				.getActiveNetworkInfo();
		if (activeNetworkInfo == null)
			return false;
		if (!activeNetworkInfo.isConnected())
			return false;
		if (!activeNetworkInfo.isAvailable())
			return false;
		return true;
	}

}
